home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / debug / Common / RelocManager.m < prev    next >
Text File  |  1994-11-29  |  9KB  |  378 lines

  1. #import "RelocManager.h"
  2. #import <stdlib.h>
  3. #import <string.h>
  4. #import <mach-o/loader.h>
  5. #import <libc.h>
  6.  
  7. @implementation RelocManager
  8.  
  9. -init
  10. {
  11.     rmFlags.invalid = YES;
  12.     rmFlags.shouldSortRelocs = YES;
  13.     return self;
  14. }
  15.  
  16. -free
  17. {
  18.     [self invalidate];
  19.     return [super free];
  20. }
  21.  
  22. int compareRelocsSort(const void *v1, const void *v2)
  23. {
  24.     const Reloc *r1 = v1, *r2 = v2;
  25.     pointer_t a1 = r1->address, a2 = r2->address;
  26.     return a1 < a2 ? -1 : (a1 == a2 ? 0 : 1);
  27. }
  28.  
  29. int compareRelocsSearch(const void *v1, const void *v2)
  30. {
  31.     const Reloc *r1 = v1, *r2 = v2;
  32.     pointer_t address = r1->address;
  33.     return address < r2->address ? -1 : (address >= r2->maxAddress ? 1 : 0);
  34. }
  35.  
  36. -(Reloc *)relocFor: (const void *)pointer
  37. {
  38.     Reloc *reloc;
  39.     int count;
  40.     BOOL found, tooFar;
  41.     if (rmFlags.invalid)
  42.     [self readInAllRelocs];
  43.     if (lastReloc
  44.     && (lastReloc->address <= (pointer_t)pointer) 
  45.     && ((pointer_t)pointer < (lastReloc->maxAddress)))
  46.     return lastReloc;
  47.     else {
  48. #if 1 
  49.     Reloc keyReloc;
  50.     keyReloc.address = (pointer_t)pointer;
  51.     if (reloc = bsearch(&keyReloc, relocs, numRelocs, relocSize, compareRelocsSearch))
  52.         found = YES;
  53.     else
  54.         found = NO;
  55. #else
  56.     reloc = relocs;
  57.     for (count = numRelocs, found = NO, tooFar = NO;
  58.          count && !found && !tooFar; count--) {
  59.         if ((pointer_t)pointer < (reloc->maxAddress)) {
  60.         if (reloc->address <= (pointer_t)pointer)
  61.             found = YES;
  62.         else
  63.             tooFar = YES;
  64.         } else
  65.         ((void *)reloc) += relocSize;
  66.     }
  67. #endif
  68.     if (found && (reloc->rFlags.readIn || [self readInReloc: reloc])) {
  69.         lastReloc = reloc;
  70.         return reloc;
  71.     } else
  72.         return NULL;
  73.     }
  74. }
  75.  
  76. -(BOOL)readInReloc: (Reloc *)reloc
  77. {
  78.     [self subclassResponsibility: _cmd];
  79.     return NO;
  80. }
  81.  
  82. -(void)_readInAllRelocs
  83. {
  84.     [self subclassResponsibility: _cmd];
  85. }
  86.  
  87. -(void)readInAllRelocs
  88. {
  89.     [self _readInAllRelocs];
  90.     if (rmFlags.shouldSortRelocs)
  91.     qsort(relocs, numRelocs, relocSize, compareRelocsSort);
  92. }
  93.  
  94. -invalidate
  95. {
  96.     if (rmFlags.invalid)
  97.     return self;
  98.     else {
  99.     if (relocs) {
  100.         free(relocs); relocs = NULL;
  101.     }
  102.     numRelocs = 0;
  103.     lastReloc = NULL;
  104.     rmFlags.invalid = YES;
  105.     return self;
  106.     }
  107. }
  108.  
  109. -(Reloc *)oldRelocFor: (const void *)pointer
  110. {
  111.    int count;
  112.    BOOL found;
  113.    Reloc *reloc;
  114.     if (lastReloc
  115.     && (lastReloc->data <= (pointer_t)pointer) 
  116.     && ((pointer_t)pointer < lastReloc->maxData))
  117.     return lastReloc;
  118.     else {
  119.     reloc = relocs;
  120.     for (count = numRelocs, found = NO; count && !found; count--) {
  121.         if (reloc->rFlags.readIn && (reloc->data <= (pointer_t)pointer) 
  122.         && ((pointer_t)pointer < reloc->maxData))
  123.         found = YES;
  124.         else
  125.         ((void *)reloc) += relocSize;
  126.     }
  127.     if (found) {
  128.         lastReloc = reloc;
  129.         return reloc;
  130.     } else
  131.         return NULL;
  132.     }
  133. }
  134.  
  135. -(void *)originalPointerFor: (const void *)pointer
  136. {    
  137.     Reloc *reloc = [self oldRelocFor: pointer];
  138.     if (reloc)
  139.     return (void *)(reloc->address + (pointer - reloc->data));
  140.     else 
  141.     return NULL;
  142. }
  143.  
  144. -(void *)pointerFor: (const void *)pointer
  145. {
  146.     Reloc *reloc;
  147.     if (pointer && (reloc = [self  relocFor: pointer])) 
  148.     return (void *)((pointer_t)pointer + reloc->displacement);
  149.     else
  150.     return NULL;
  151. }
  152.  
  153. -(char *)pointerForString: (const char *)pointer isNullTerminated: (BOOL *)isNT
  154. {
  155.     char *retPointer;
  156.     Reloc *reloc;
  157.     char *string;
  158.     if (pointer && (reloc = [self relocFor: pointer])) {
  159.         retPointer = (char *)((pointer_t)pointer + reloc->displacement);
  160.     for (string = retPointer;
  161.          *string && ((pointer_t)string < reloc->maxData);
  162.          string++);
  163.     *isNT = *string ? NO : YES;
  164.     return retPointer;
  165.     } else{
  166.     *isNT = NO;
  167.     return NULL;
  168.     }
  169. }
  170.  
  171. -(char *)pointerForString: (const char *)string
  172. {
  173.     BOOL isNT;
  174.     char *retPointer;
  175.     if ((retPointer = [self pointerForString: string isNullTerminated: &isNT])
  176.     && isNT)
  177.     return retPointer;
  178.     else
  179.     return NULL;
  180. }
  181.  
  182. -(void *)pointerFor: (const void *)pointer withSize: (int)size
  183. {
  184.     Reloc *reloc;
  185.     pointer_t newPointer;
  186.     if (pointer && (reloc = [self relocFor: pointer])) {
  187.     newPointer = (pointer_t)pointer + reloc->displacement;
  188.     if ((newPointer + size) <= reloc->maxData)
  189.         return (void *)newPointer;
  190.     else
  191.         return NULL;
  192.     } else
  193.     return NULL;
  194. }
  195.  
  196. -(id)pointerForID: (const id)pointer
  197. {
  198.     Class theClass;
  199.     struct _ObjectID {
  200.     @defs(Object)
  201.     } *newID;
  202.     
  203.     if (pointer
  204.         && (newID = [self pointerFor: pointer withSize: sizeof(id)])
  205.     && (theClass = [self pointerFor: newID->isa
  206.                            withSize: sizeof(Class)])
  207.     && (newID
  208.         = [self pointerFor: pointer withSize: theClass->instance_size]))
  209.     return (id)newID;
  210.     else
  211.     return nil;
  212. }
  213.             
  214. -(int)getDataAt: (const void *)start for: (int)numBytes into: (void *)data
  215. {
  216.     Reloc *reloc = [self relocFor: start];
  217.     int numBytesInReloc;
  218.     
  219.     if (reloc) {
  220.         numBytesInReloc = reloc->maxAddress - (int)start;
  221.         if (numBytes > numBytesInReloc)
  222.         numBytes = numBytesInReloc;
  223.     memcpy(data,
  224.            (void *)(reloc->data + ((pointer_t)start - reloc->address)),
  225.            numBytes);
  226.     return numBytes;
  227.     } else
  228.     return 0;
  229. }
  230.  
  231. -(struct mach_header *)getMachHeader
  232. {
  233.     [self subclassResponsibility: _cmd];
  234.     return NULL;
  235. }
  236.  
  237. -(int)getNumMachHeaders
  238. {
  239.     [self subclassResponsibility: _cmd];
  240.     return 0;
  241. }
  242.  
  243. -(struct mach_header **)getMachHeaders
  244. {
  245.     [self subclassResponsibility: _cmd];
  246.     return NULL;
  247. }
  248.  
  249. -(struct mach_header **)getMachHeadersWithNames: (char ***)names
  250. {
  251.     [self subclassResponsibility: _cmd];
  252.     return NULL;
  253. }
  254.  
  255. -(void *)getSectData: (STR)segName 
  256.          section: (STR)sectName 
  257.         size: (int *)pSize 
  258.        forHeader: (struct mach_header *)header
  259. {
  260.     void *data = getsectdatafromheader(header, segName, sectName, pSize);
  261.     return [self pointerFor: data withSize: *pSize];
  262. }
  263.  
  264. -(void *)getSectData: (STR)segName 
  265.          section: (STR)sectName 
  266.         size: (int *)pSize 
  267. {
  268.     return [self getSectData: segName 
  269.              section: sectName 
  270.             size: pSize 
  271.            forHeader: [self getMachHeader]];
  272. }
  273.  
  274. -(const struct section *)getSeg: (STR)segName sect: (STR)sectName
  275. {
  276.     return getsectbynamefromheader([self getMachHeader], segName, sectName);
  277. }
  278.  
  279. -(const struct section *)firstSection
  280. {
  281.     struct mach_header *header = [self getMachHeader];
  282.     int i;
  283.     struct load_command *loadCmd;
  284.     
  285.     for (i = 0, loadCmd = (struct load_command *)(header + 1);
  286.      i < header->ncmds;
  287.      i++, ((void *)loadCmd) += loadCmd->cmdsize) {
  288.     if (loadCmd->cmd == LC_SEGMENT) {
  289.         struct segment_command *segCmd = (struct segment_command *)loadCmd;
  290.         if (segCmd->nsects)
  291.         return (struct section *)(segCmd + 1);
  292.     }
  293.     }
  294.     return NULL;
  295. }
  296.         
  297. -(unsigned)getMaximumAddressForHeader: (struct mach_header *)header
  298. {
  299.     int i;
  300.     struct load_command *loadCmd;
  301.     unsigned maxAddr = 0;
  302.     
  303.     for (i = 0, loadCmd = (struct load_command *)(header + 1);
  304.      i < header->ncmds;
  305.      i++, ((void *)loadCmd) += loadCmd->cmdsize) {
  306.     if (loadCmd->cmd == LC_SEGMENT) {
  307.         struct segment_command *segCmd = (struct segment_command *)loadCmd;
  308.         if ((segCmd->vmaddr + segCmd->vmsize) > maxAddr)
  309.         maxAddr = segCmd->vmaddr + segCmd->vmsize;
  310.     }
  311.     }
  312.     return maxAddr;
  313. }
  314.  
  315. -(struct segment_command *)getSegment: (const char *)segName
  316. {
  317.     int i;
  318.     struct load_command *loadCmd;
  319.     struct segment_command *foundSeg = NULL;
  320.     struct mach_header *header = [self getMachHeader];
  321.     
  322.     for (i = 0, loadCmd = (struct load_command *)(header + 1);
  323.      i < header->ncmds && !foundSeg;
  324.      i++, ((void *)loadCmd) += loadCmd->cmdsize) {
  325.     if (loadCmd->cmd == LC_SEGMENT) {
  326.         struct segment_command *segCmd = (struct segment_command *)loadCmd;
  327.         if (strcmp(segName, segCmd->segname) == 0)
  328.         foundSeg = segCmd;
  329.     }
  330.     }
  331.     return foundSeg;
  332. }
  333.  
  334. -(unsigned)getMaximumAddressForSegment: (const char *)segName
  335. {
  336.     int i;
  337.     struct load_command *loadCmd;
  338.     unsigned maxAddr = 0;
  339.     struct mach_header *header = [self getMachHeader];
  340.     
  341.     for (i = 0, loadCmd = (struct load_command *)(header + 1);
  342.      i < header->ncmds;
  343.      i++, ((void *)loadCmd) += loadCmd->cmdsize) {
  344.     if (loadCmd->cmd == LC_SEGMENT) {
  345.         struct segment_command *segCmd = (struct segment_command *)loadCmd;
  346.         struct section *section;
  347.         int nSects;
  348.         
  349.         for (nSects = segCmd->nsects,
  350.              section = (struct section *)(segCmd + 1);
  351.              nSects;
  352.          nSects--, section++) {
  353.         if (strcmp(section->segname, segName) == 0) {
  354.             if ((section->addr + section->size) > maxAddr)
  355.             maxAddr = (section->addr + section->size);
  356.         }
  357.         }
  358.     }
  359.     }
  360.     return maxAddr;
  361. }
  362.  
  363. -(unsigned)getMaximumAddress
  364. {
  365.     return [self getMaximumAddressForHeader: [self getMachHeader]];
  366. }
  367.  
  368. -(unsigned)getMaximumTextAddress
  369. {
  370.     return [self getMaximumAddressForSegment: "__TEXT"];
  371. }
  372.  
  373. -(unsigned)getMaximumDataAddress
  374. {
  375.     return [self getMaximumAddressForSegment: "__DATA"];
  376. }
  377.  
  378. @end